package db

import (
	"encoding/json"
	"errors"
	"fmt"
	"go.etcd.io/bbolt"
	"greatTool/conf"
	"greatTool/models"
	"os"
	"path/filepath"
	"sort"
)

// Storage 定义存储接口
type Storage interface {
	Init() error
	Close() error
	GetAllResources() (map[models.ValJsonKey]models.ValJson, error)
	SaveResource(key models.ValJsonKey, value models.ValJson) error
	DeleteResource(key models.ValJsonKey) error
	UpdateResource(key models.ValJsonKey, newValue models.ValJson) error
	SaveAuditRecord(record models.AuditRecord) error
	GetAuditStats() (models.AuditStats, error)
	DeleteAuditRecords(resourceKey string) error
	SaveHistoryRecord(record models.HistoryRecord) error
	GetAllHistoryRecords() ([]models.HistoryRecord, error)
	GetHistoryRecord(index int, order models.SortOrder) (models.HistoryRecord, error)
	GetHistoryStats() (models.HistoryStats, error)
	DeleteHistoryRecords(resourceKey string) error
}

// ==================== 本地存储实现 ====================

// LocalStorage 本地存储实现
type LocalStorage struct {
	db     *bbolt.DB
	dbPath string
}

// NewLocalStorage 创建本地存储实例
func NewLocalStorage() *LocalStorage {
	return &LocalStorage{}
}

// Init 初始化本地数据库
func (ls *LocalStorage) Init() error {
	// 如果 dbPath 未设置，则使用默认路径
	if ls.dbPath == "" {
		dbPath, err := GetDBPath()
		if err != nil {
			return err
		}
		ls.dbPath = dbPath
	}

	// 确保目录存在
	if err := os.MkdirAll(filepath.Dir(ls.dbPath), 0755); err != nil {
		return fmt.Errorf("创建目录失败: %w", err)
	}

	// 打开数据库
	db, err := bbolt.Open(ls.dbPath, 0600, nil)
	if err != nil {
		return fmt.Errorf("打开数据库失败: %w", err)
	}
	ls.db = db

	// 创建必要的 bucket
	return ls.db.Update(func(tx *bbolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte("resources"))
		return err
	})
}

// Close 关闭数据库
func (ls *LocalStorage) Close() error {
	if ls.db != nil {
		return ls.db.Close()
	}
	return nil
}

// GetAllResources 获取所有资源
func (ls *LocalStorage) GetAllResources() (map[models.ValJsonKey]models.ValJson, error) {
	resources := make(map[models.ValJsonKey]models.ValJson)

	err := ls.db.View(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("resources"))
		if bucket == nil {
			return errors.New("资源桶不存在")
		}

		return bucket.ForEach(func(k, v []byte) error {
			var key models.ValJsonKey
			if err := json.Unmarshal(k, &key); err != nil {
				return fmt.Errorf("解析key失败: %w", err)
			}

			var val models.ValJson
			if err := json.Unmarshal(v, &val); err != nil {
				return fmt.Errorf("解析value失败: %w", err)
			}

			resources[key] = val
			return nil
		})
	})

	return resources, err
}

// SaveResource 保存资源
func (ls *LocalStorage) SaveResource(key models.ValJsonKey, value models.ValJson) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("resources"))
		if bucket == nil {
			return errors.New("资源桶不存在")
		}

		keyBytes, err := json.Marshal(key)
		if err != nil {
			return fmt.Errorf("序列化key失败: %w", err)
		}

		valBytes, err := json.Marshal(value)
		if err != nil {
			return fmt.Errorf("序列化value失败: %w", err)
		}

		return bucket.Put(keyBytes, valBytes)
	})
}

// DeleteResource 删除资源
func (ls *LocalStorage) DeleteResource(key models.ValJsonKey) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("resources"))
		if bucket == nil {
			return errors.New("资源桶不存在")
		}

		keyBytes, err := json.Marshal(key)
		if err != nil {
			return fmt.Errorf("序列化key失败: %w", err)
		}

		return bucket.Delete(keyBytes)
	})
}

// UpdateResource 更新资源
func (ls *LocalStorage) UpdateResource(key models.ValJsonKey, newValue models.ValJson) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("resources"))
		if bucket == nil {
			return errors.New("资源桶不存在")
		}

		keyBytes, err := json.Marshal(key)
		if err != nil {
			return fmt.Errorf("序列化key失败: %w", err)
		}

		valBytes, err := json.Marshal(newValue)
		if err != nil {
			return fmt.Errorf("序列化value失败: %w", err)
		}

		return bucket.Put(keyBytes, valBytes)
	})
}

// ==================== 云端存储实现 ====================

// CloudStorage 云端存储实现
type CloudStorage struct {
	apiURL  string
	apiKey  string
	timeout int
	// 可以添加其他云存储相关字段
}

// NewCloudStorage 创建云端存储实例
func NewCloudStorage(apiURL, apiKey string, timeout int) *CloudStorage {
	return &CloudStorage{
		apiURL:  apiURL,
		apiKey:  apiKey,
		timeout: timeout,
	}
}

func (cs *CloudStorage) Init() error {
	// 初始化云存储连接，比如验证API密钥等
	fmt.Printf("初始化云存储连接: %s\n", cs.apiURL)
	// 实际实现中这里会有网络连接和认证逻辑
	return nil
}

func (cs *CloudStorage) Close() error {
	// 关闭云存储连接
	fmt.Println("关闭云存储连接")
	return nil
}

func (cs *CloudStorage) GetAllResources() (map[models.ValJsonKey]models.ValJson, error) {
	// 实现从云端获取所有资源的逻辑
	fmt.Println("从云端获取所有资源")
	// 实际实现中这里会有HTTP请求逻辑
	return make(map[models.ValJsonKey]models.ValJson), nil
}

func (cs *CloudStorage) SaveResource(key models.ValJsonKey, _ models.ValJson) error {
	// 实现保存资源到云端的逻辑
	fmt.Printf("保存资源到云端: %+v\n", key)
	// 实际实现中这里会有HTTP POST/PUT请求逻辑
	return nil
}

func (cs *CloudStorage) DeleteResource(key models.ValJsonKey) error {
	// 实现从云端删除资源的逻辑
	fmt.Printf("从云端删除资源: %+v\n", key)
	// 实际实现中这里会有HTTP DELETE请求逻辑
	return nil
}

func (cs *CloudStorage) UpdateResource(key models.ValJsonKey, _ models.ValJson) error {
	// 实现更新云端资源的逻辑
	fmt.Printf("更新云端资源: %+v\n", key)
	// 实际实现中这里会有HTTP PUT/PATCH请求逻辑
	return nil
}

// ==================== 同步存储实现（本地+云端） ====================

// SyncStorage 同步存储实现（同时保存到本地和云端）
type SyncStorage struct {
	localStorage Storage
	cloudStorage Storage
}

// NewSyncStorage 创建同步存储实例
func NewSyncStorage(local Storage, cloud Storage) *SyncStorage {
	return &SyncStorage{
		localStorage: local,
		cloudStorage: cloud,
	}
}

func (ss *SyncStorage) Init() error {
	// 初始化本地和云端存储
	if err := ss.localStorage.Init(); err != nil {
		return err
	}
	return ss.cloudStorage.Init()
}

func (ss *SyncStorage) Close() error {
	// 关闭本地和云端存储
	if err := ss.localStorage.Close(); err != nil {
		return err
	}
	return ss.cloudStorage.Close()
}

func (ss *SyncStorage) GetAllResources() (map[models.ValJsonKey]models.ValJson, error) {
	// 优先从本地获取，如果本地没有再从云端同步
	return ss.localStorage.GetAllResources()
}

func (ss *SyncStorage) SaveResource(key models.ValJsonKey, value models.ValJson) error {
	// 同时保存到本地和云端
	if err := ss.localStorage.SaveResource(key, value); err != nil {
		return err
	}
	return ss.cloudStorage.SaveResource(key, value)
}

func (ss *SyncStorage) DeleteResource(key models.ValJsonKey) error {
	// 同时从本地和云端删除
	if err := ss.localStorage.DeleteResource(key); err != nil {
		return err
	}
	return ss.cloudStorage.DeleteResource(key)
}

func (ss *SyncStorage) UpdateResource(key models.ValJsonKey, newValue models.ValJson) error {
	// 同时更新本地和云端
	if err := ss.localStorage.UpdateResource(key, newValue); err != nil {
		return err
	}
	return ss.cloudStorage.UpdateResource(key, newValue)
}

// ==================== 工具函数 ====================

// GetDBPath 获取数据库文件路径
func GetDBPath() (string, error) {
	ttlConf, err := conf.GetTtlConf()
	if err != nil {
		return "", err
	}
	return ttlConf.DbPath, nil
}

// SaveAuditRecord 保存审计记录
func (ls *LocalStorage) SaveAuditRecord(record models.AuditRecord) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("audit"))
		if bucket == nil {
			bucket, _ = tx.CreateBucket([]byte("audit"))
		}

		key := fmt.Sprintf("%s_%s_%d", record.ResourceKey, record.Operation, record.Timestamp)
		valBytes, err := json.Marshal(record)
		if err != nil {
			return fmt.Errorf("序列化审计记录失败: %w", err)
		}

		return bucket.Put([]byte(key), valBytes)
	})
}

// GetAuditStats 获取审计统计
func (ls *LocalStorage) GetAuditStats() (models.AuditStats, error) {
	stats := models.AuditStats{
		ByOperation: make(map[string]int),
		ByResource:  make(map[string]int),
	}

	err := ls.db.View(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("audit"))
		if bucket == nil {
			return nil // 没有审计记录
		}

		return bucket.ForEach(func(k, v []byte) error {
			var record models.AuditRecord
			if err := json.Unmarshal(v, &record); err != nil {
				return fmt.Errorf("解析审计记录失败: %w", err)
			}

			stats.TotalOperations += record.Count
			stats.ByOperation[record.Operation] += record.Count
			stats.ByResource[record.ResourceKey] += record.Count

			return nil
		})
	})

	return stats, err
}

// DeleteAuditRecords 删除资源的审计记录
func (ls *LocalStorage) DeleteAuditRecords(resourceKey string) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("audit"))
		if bucket == nil {
			return nil // 没有审计记录
		}

		// 查找并删除该资源的所有审计记录
		var toDelete [][]byte
		err := bucket.ForEach(func(k, v []byte) error {
			var record models.AuditRecord
			if err := json.Unmarshal(v, &record); err != nil {
				return err
			}

			if record.ResourceKey == resourceKey {
				toDelete = append(toDelete, k)
			}
			return nil
		})

		if err != nil {
			return err
		}

		// 删除找到的记录
		for _, key := range toDelete {
			if err := bucket.Delete(key); err != nil {
				return err
			}
		}

		return nil
	})
}

// SaveAuditRecord 在 CloudStorage 和 SyncStorage 中也添加相应的空实现（为了接口兼容）
func (cs *CloudStorage) SaveAuditRecord(record models.AuditRecord) error {
	fmt.Printf("保存审计记录到云端: %+v\n", record)
	return nil
}

func (cs *CloudStorage) GetAuditStats() (models.AuditStats, error) {
	fmt.Println("从云端获取审计统计")
	return models.AuditStats{
		ByOperation: make(map[string]int),
		ByResource:  make(map[string]int),
	}, nil
}

func (cs *CloudStorage) DeleteAuditRecords(resourceKey string) error {
	fmt.Printf("从云端删除审计记录: %s\n", resourceKey)
	return nil
}

// SaveAuditRecord SyncStorage 的相应方法
func (ss *SyncStorage) SaveAuditRecord(record models.AuditRecord) error {
	if err := ss.localStorage.SaveAuditRecord(record); err != nil {
		return err
	}
	return ss.cloudStorage.SaveAuditRecord(record)
}

func (ss *SyncStorage) GetAuditStats() (models.AuditStats, error) {
	return ss.localStorage.GetAuditStats()
}

func (ss *SyncStorage) DeleteAuditRecords(resourceKey string) error {
	if err := ss.localStorage.DeleteAuditRecords(resourceKey); err != nil {
		return err
	}
	return ss.cloudStorage.DeleteAuditRecords(resourceKey)
}

// SaveHistoryRecord 保存详细历史记录
func (ls *LocalStorage) SaveHistoryRecord(record models.HistoryRecord) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("history"))
		if bucket == nil {
			bucket, _ = tx.CreateBucket([]byte("history"))
		}

		// 使用时间戳+随机数作为key，确保唯一性
		key := fmt.Sprintf("%d_%d", record.Timestamp, record.ID)
		valBytes, err := json.Marshal(record)
		if err != nil {
			return fmt.Errorf("序列化历史记录失败: %w", err)
		}

		return bucket.Put([]byte(key), valBytes)
	})
}

// GetAllHistoryRecords 获取所有历史记录
func (ls *LocalStorage) GetAllHistoryRecords() ([]models.HistoryRecord, error) {
	var records []models.HistoryRecord

	err := ls.db.View(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("history"))
		if bucket == nil {
			return nil // 没有历史记录
		}

		return bucket.ForEach(func(k, v []byte) error {
			var record models.HistoryRecord
			if err := json.Unmarshal(v, &record); err != nil {
				return fmt.Errorf("解析历史记录失败: %w", err)
			}
			records = append(records, record)
			return nil
		})
	})

	// 按时间倒序排序
	sort.Slice(records, func(i, j int) bool {
		return records[i].Timestamp > records[j].Timestamp
	})

	return records, err
}

// GetHistoryRecord 获取指定位置的历史记录
func (ls *LocalStorage) GetHistoryRecord(index int, order models.SortOrder) (models.HistoryRecord, error) {
	var record models.HistoryRecord
	var found bool

	err := ls.db.View(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("history"))
		if bucket := tx.Bucket([]byte("history")); bucket == nil {
			return fmt.Errorf("history bucket does not exist")
		}

		cursor := bucket.Cursor()

		// 先获取总记录数
		total := 0
		for k, _ := cursor.First(); k != nil; k, _ = cursor.Next() {
			total++
		}

		if index < 0 || index >= total {
			return nil // 索引超出范围
		}

		var targetIndex int
		if order == models.Descending {
			// 倒序：索引转换
			targetIndex = total - 1 - index
		} else if order == models.Ascending {
			// 正序：直接使用索引
			targetIndex = index
		}

		// 遍历到目标位置
		idx := 0
		for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
			if idx == targetIndex {
				if err := json.Unmarshal(v, &record); err != nil {
					return fmt.Errorf("failed to unmarshal record: %w", err)
				}
				found = true
				return nil
			}
			idx++
		}

		return nil
	})

	if err != nil {
		return models.HistoryRecord{}, err
	}

	if !found {
		return models.HistoryRecord{}, fmt.Errorf("index %d out of bounds", index)
	}

	return record, nil
}

// GetHistoryStats 获取历史统计
func (ls *LocalStorage) GetHistoryStats() (models.HistoryStats, error) {
	stats := models.HistoryStats{
		ByOperation: make(map[string]int),
		ByResource:  make(map[string]int),
	}

	records, err := ls.GetAllHistoryRecords()
	if err != nil {
		return stats, err
	}

	stats.TotalRecords = len(records)
	stats.Records = records

	for _, record := range records {
		stats.ByOperation[record.Operation]++
		stats.ByResource[record.ResourceKey]++
	}

	return stats, nil
}

// DeleteHistoryRecords 删除资源的历史记录
func (ls *LocalStorage) DeleteHistoryRecords(resourceKey string) error {
	return ls.db.Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket([]byte("history"))
		if bucket == nil {
			return nil // 没有历史记录
		}

		// 查找并删除该资源的所有历史记录
		var toDelete [][]byte
		err := bucket.ForEach(func(k, v []byte) error {
			var record models.HistoryRecord
			if err := json.Unmarshal(v, &record); err != nil {
				return err
			}

			if record.ResourceKey == resourceKey {
				toDelete = append(toDelete, k)
			}
			return nil
		})

		if err != nil {
			return err
		}

		// 删除找到的记录
		for _, key := range toDelete {
			if err := bucket.Delete(key); err != nil {
				return err
			}
		}

		return nil
	})
}

// SaveHistoryRecord 在 CloudStorage 和 SyncStorage 中也添加相应的空实现
func (cs *CloudStorage) SaveHistoryRecord(record models.HistoryRecord) error {
	fmt.Printf("保存历史记录到云端: %+v\n", record)
	return nil
}

func (cs *CloudStorage) GetAllHistoryRecords() ([]models.HistoryRecord, error) {
	fmt.Println("从云端获取所有历史记录")
	return []models.HistoryRecord{}, nil
}

// GetHistoryRecord 获取具体位置的历史记录
func (cs *CloudStorage) GetHistoryRecord(index int, _ models.SortOrder) (models.HistoryRecord, error) {
	fmt.Printf("从云端获取历史记录: %+v\n", index)
	return models.HistoryRecord{}, nil
}

func (cs *CloudStorage) GetHistoryStats() (models.HistoryStats, error) {
	fmt.Println("从云端获取历史统计")
	return models.HistoryStats{
		ByOperation: make(map[string]int),
		ByResource:  make(map[string]int),
	}, nil
}

func (cs *CloudStorage) DeleteHistoryRecords(resourceKey string) error {
	fmt.Printf("从云端删除历史记录: %s\n", resourceKey)
	return nil
}

// SaveHistoryRecord SyncStorage 的相应方法
func (ss *SyncStorage) SaveHistoryRecord(record models.HistoryRecord) error {
	if err := ss.localStorage.SaveHistoryRecord(record); err != nil {
		return err
	}
	return ss.cloudStorage.SaveHistoryRecord(record)
}

func (ss *SyncStorage) GetAllHistoryRecords() ([]models.HistoryRecord, error) {
	return ss.localStorage.GetAllHistoryRecords()
}

// GetHistoryRecord 获取具体位置的历史记录
func (ss *SyncStorage) GetHistoryRecord(index int, order models.SortOrder) (models.HistoryRecord, error) {
	return ss.localStorage.GetHistoryRecord(index, order)
}

func (ss *SyncStorage) GetHistoryStats() (models.HistoryStats, error) {
	return ss.localStorage.GetHistoryStats()
}

func (ss *SyncStorage) DeleteHistoryRecords(resourceKey string) error {
	if err := ss.localStorage.DeleteHistoryRecords(resourceKey); err != nil {
		return err
	}
	return ss.cloudStorage.DeleteHistoryRecords(resourceKey)
}
